package com.gitee.hermer.engine.jars.core.zipkin.configuration;

import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.gitee.hermer.engine.jars.core.context.IEngineAppContext;
import com.gitee.hermer.engine.jars.core.domain.EngineConstant;
import com.gitee.hermer.engine.jars.core.zipkin.filter.EngineZipkinTracingFilter;
import com.gitee.hermer.engine.jars.core.zipkin.interceptor.EngineZipkinSpanHandlerInterceptor;
import com.gitee.hermer.engine.jars.dependent.dsm.IEnginePropertiesAware;
import com.gitee.hermer.engine.jars.dependent.zipkin.EngineZipkinConfig;
import com.gitee.hermer.engine.jars.dependent.zipkin.config.ZipkinProperties;

import zipkin2.Span;
import zipkin2.codec.SpanBytesEncoder;
import zipkin2.reporter.AsyncReporter;
import zipkin2.reporter.Reporter;
import zipkin2.reporter.Sender;
import zipkin2.reporter.okhttp3.OkHttpSender;



@Configuration
@ComponentScan("com.gitee.hermer.engine.jars.dependent.zipkin.config")
public class EngineZipkinAutoConfiguration extends WebMvcConfigurerAdapter implements Ordered,IEnginePropertiesAware<ZipkinProperties>{

	private ZipkinProperties properties;
	
	@Override
	public int getOrder() {
		return 0;
	}
	@Bean(EngineConstant.SPRING_BEAN_NAME_ZIPKIN_CONFIG)
	public EngineZipkinConfig engineZipkinConfig(){
		return new EngineZipkinConfig(properties.getAppName(),properties.getAppVersion(),properties.getServerResAddres(),properties.getClientTimeout());
	}
	
	@Bean(name={EngineConstant.SPRING_BEAN_NAME_ZIPKIN_SENDER_BEAN})
	public Sender sender(EngineZipkinConfig config)
	{
		try{
			return OkHttpSender.create(properties.getServerResAddres());
		}catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}
	
	@Bean Reporter<Span> asyncReporterFactoryBean(Sender sender) throws Exception{
		return AsyncReporter.builder(sender)
				.closeTimeout(properties.getClientTimeout(), TimeUnit.MILLISECONDS).build(SpanBytesEncoder.JSON_V2);
	}

	@Override
	@Autowired
	public void setProperties(ZipkinProperties properties) {
		this.properties = properties;
	}
	
	
	@Bean(EngineConstant.SPRING_BEAN_NAME_ZIPKIN_TRACING_FILTER)
	public EngineZipkinTracingFilter engineZipkinTracingFilter(){
		return new EngineZipkinTracingFilter();
	}
	
	
	
	
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(new EngineZipkinSpanHandlerInterceptor()).addPathPatterns("/**");
	}
	
}
